//
// Created by hsj on 2024-1-4.
// 编译：gcc udp_hello_server_win.c -LH:\mingw\mingw64\x86_64-w64-mingw32\lib -lws2_32 -o udp_hello_server_win
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <fcntl.h>

#ifdef WIN32
//windows minGW64
//inet_ntop函数：_WIN32_WINNT
#ifdef _WIN32_WINNT
#undef _WIN32_WINNT
#endif
#define _WIN32_WINNT 0x0600
#include <winsock2.h>
#include <ws2tcpip.h>
//#pragma comment(lib,"ws2_32.lib")
#else
//linux  gcc
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#endif

#define BUF_SIZE 30
void ErrorHandling( char *message) ;

int main(int argc, char *argv[] ) {
    WSADATA wsaData;
    SOCKET servSock;
    char message[BUF_SIZE];
    int strLen;
    int clntAdrSz;
    SOCKADDR_IN servAdr, clntAdr;
    char port[] = "8888";
//    if(argc!=2) {
//        printf("Usage : %s <port>\n", argv[0]);
//        exit(1);
//    }
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
        ErrorHandling("WSAStartup() error!");

    servSock = socket(PF_INET, SOCK_DGRAM, 0);
    if (servSock == INVALID_SOCKET)
        ErrorHandling("UDP socket creation error");

    memset(&servAdr, 0, sizeof(servAdr));
    servAdr.sin_family=AF_INET;
    servAdr.sin_addr.s_addr=htonl(INADDR_ANY);
    servAdr.sin_port=htons(atoi(/*argv[1]*/port));

    if(bind(servSock, (SOCKADDR*)&servAdr, sizeof(servAdr))==SOCKET_ERROR)
        ErrorHandling( "bind() error");
    printf("windows [udp] service listen on port: %s\n",port);

    while(1){//死循环
        clntAdrSz=sizeof(clntAdr);
        strLen=recvfrom(servSock,message,BUF_SIZE, 0,(SOCKADDR* )&clntAdr, &clntAdrSz);

        //获取client端的IP和端口
        //xxx.xxx.xxx.xxx = 15位
        char strClientIP[16];
        memset(strClientIP, 0, sizeof(strClientIP));
        printf("client-->IP:[%s],PORT:[%d]\n", inet_ntop(AF_INET, &clntAdr.sin_addr.s_addr, strClientIP, sizeof(strClientIP)), ntohs(clntAdr.sin_port));

        sendto(servSock, message, strLen, 0,(SOCKADDR* )&clntAdr, sizeof( clntAdr));
    }
    closesocket(servSock);
    WSACleanup( );

    return EXIT_SUCCESS;
}

void ErrorHandling( char *message ){
    fputs(message, stderr);
    fputc('\n' , stderr);
    exit(1);
}
